#include <QtCore/QDir>
#include <QtCore/QDate>
#include <QtCore/QSettings>
#include <QtGui/QMenuBar>
#include <QtGui/QMessageBox>
#include <QtGui/QCloseEvent>
#include "qastrologer.h"
#include "qzodiac.h"
#include "qhtmlparser.h"
#include "ihttpclient.h"
#include "qhttpclient_qhttp.h"
#ifndef Q_OS_SYMBIAN
#include "chttpclient.h"
#endif
#include "qproxydialog.h"
#include "mainwindow.h"


GoThread::GoThread(const QDate &dtDate, const QZodiac::ZodiacIndex &idxZodiac)
    : m_dtDate(dtDate), m_idxZodiac(idxZodiac)
{

}

GoThread::~GoThread()
{
    if (m_pHttpClient) {
        m_pHttpClient->release();
        m_pHttpClient = 0;
    }
}

void GoThread::run()
{
    emit this->showMessage("Please wait...");

    QString strDate = QString("%1%2%3").arg(m_dtDate.year())
        .arg(m_dtDate.month(), 2, 10, QChar('0')).arg(m_dtDate.day(), 2, 10, QChar('0'));
    QString strZodiac = QZodiac::allInstance().at((int)m_idxZodiac).name().toLower();

    QDir tempDir = QDir::temp();
    QString tempName = QString("ast_%1_%2.htm").arg(strDate, strZodiac);
    QString tempPath = tempDir.absoluteFilePath(tempName);
    // http://mindcity.sina.com.tw/MC_data/west/MC-12horos/day/20100101/aquarius.shtml
    QString urlPath = QString("http://mindcity.sina.com.tw/MC_data/west/MC-12horos/day/%1/%2.shtml").arg(strDate, strZodiac);

    QSettings settings(QAS_APP_NAME, "proxy");
    bool enable = settings.value("enable").toBool();
    QString address = settings.value("address").toString();
    int port = settings.value("port").toInt();
    QString username = settings.value("username").toString();
    QString password = settings.value("password").toString();
    QString domain = settings.value("domain").toString();

#ifdef Q_OS_SYMBIAN
    /*
     * We create the Http client in second thread.
     * Due to Qt's per-thread event model, we should not create and use a QObject in different threads.
     */
    m_pHttpClient = new QHttpClient_QHttp;
#else
    m_pHttpClient = new CHttpClient;
#endif
    if (enable) {
        m_pHttpClient->setProxy(qPrintable(address), port, qPrintable(username), qPrintable(password), qPrintable(domain));
    }
    if (m_pHttpClient->getUrlToFile(qPrintable(urlPath), qPrintable(tempPath))) {
        QHtmlParser parser(tempPath);
        QZodiac zodiac = QZodiac::allInstance().at((int)m_idxZodiac);
        QString allContents = parser.getAllFormatted(QDate::fromString(strDate, "yyyyMMdd"), zodiac);
        emit this->showMessage(allContents);
    } else {
        emit this->showMessage("There seems to be a network error...");
    }
    m_pHttpClient->release();
    m_pHttpClient = 0;

    QFile::remove(tempPath);
}

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), m_goThread(0)
{
    setupUi(this);
    this->init();
    this->connect(bnGo, SIGNAL(clicked()), this, SLOT(go()));
    this->connect(bnAbout, SIGNAL(clicked()), this, SLOT(about()));
    this->connect(bnProxy, SIGNAL(clicked()), this, SLOT(proxy()));
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    this->stop();
    event->accept();
}

bool MainWindow::init()
{
    // size mode
    this->setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint & ~Qt::WindowMaximizeButtonHint);
    // date edit
    deDate->setCalendarPopup(true);
    deDate->setDate(QDate::currentDate());
    // zodiac combobox
    QList<QZodiac> zodiacList = QZodiac::allInstance();
    for (int i = 0; i < zodiacList.size(); i++) {
        QZodiac zodiac = zodiacList.at(i);
        cbZodiac->addItem(zodiac.name());
    }
    cbZodiac->setMaxVisibleItems(zodiacList.size());
    cbZodiac->setCurrentIndex((int)QZodiac::Aquarius);
    // go button
    bnGo->setFocus();
    bnGo->setDefault(true);
    // grid stretch
    gridLayout->setColumnStretch(1, 10);

#ifdef Q_OS_SYMBIAN
    // hide proxy/about buttons
    bnProxy->setVisible(false);
    bnAbout->setVisible(false);
    verticalLayout->removeItem(horizontalLayout);
    delete horizontalLayout;
    // remove context menu
    QWidgetList widgets = QApplication::allWidgets();
    foreach(QWidget *w, widgets) {
        w->setContextMenuPolicy(Qt::NoContextMenu);
    }
    edContent->setReadOnly(true);
    edContent->setContextMenuPolicy(Qt::DefaultContextMenu);
    // add about option menu
    aboutAct = new QAction(("&About"), this);
    menuBar()->addAction(aboutAct);
    connect(aboutAct, SIGNAL(triggered()),this, SLOT(about()));
#endif

    return true;
}

void MainWindow::setContent(const QString &strContent)
{
    edContent->setText(strContent);
}

void MainWindow::go()
{
    QDate dtDate = deDate->date();
    QZodiac::ZodiacIndex idxZodiac = (QZodiac::ZodiacIndex)cbZodiac->currentIndex();

    this->stop();
    m_goThread = new GoThread(dtDate, idxZodiac);
    this->connect(m_goThread, SIGNAL(showMessage(const QString &)), this, SLOT(setContent(const QString &)));
    m_goThread->start();
}

void MainWindow::about()
{
    QMessageBox::about(this, "About",
        QString("%1 %2%4%3%4").arg(QAS_APP_NAME, QAS_VERSION, "(C) 2011 gonwan. This is free software.", QString(QChar::LineSeparator)));
}

void MainWindow::proxy()
{
    QProxyDialog proxyDialog(this);
    proxyDialog.exec();
}

void MainWindow::stop()
{
    if (m_goThread) {
        /*
         * Not sure why exit() not working.
         */
        m_goThread->terminate();
        delete m_goThread;
        m_goThread = 0;
    }
}
